#import "FlutterIotPlugin.h"

#if __has_include(<flutter_iot_plugin/flutter_iot_plugin-Swift.h>)
#import <flutter_iot_plugin/flutter_iot_plugin-Swift.h>
#else
// Support project import fallback if the generated compatibility header
// is not copied when this plugin is created as a library.
// https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816
#import "flutter_iot_plugin-Swift.h"
#endif

#import <ALBBOpenAccountSSO/ALBBOpenAccountSSOSDK.h>
#define OPEN_LOG
#ifdef  OPEN_LOG
//__LINE__ 代表行数,  __PRETTY_FUNCTION__ 代表当前的函数名
#define DLOG(fmt, ...)      NSLog((@"[Line %d] %s\n" fmt), __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__);
#else
#define DLOG(fmt, ...)
#endif

// 阿里飞燕平台 SDk 为何报错找不到 #import <IMLDeviceCenter/IMLDeviceCenter.h> 头文件？
//https://docs.espressif.com/projects/espressif-esp-faq/zh_CN/latest/application-solution/ios-application.html

FLTFlutterAliLink *flutterAliLink;

@interface FlutterIotPlugin ()<SSODelegate>
@end

@implementation FlutterIotPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  FlutterIotPlugin *plugin = [[FlutterIotPlugin alloc] init];
  // 注册api
  FLTHostAliLinkSetup(registrar.messenger, plugin);
  flutterAliLink = [[FLTFlutterAliLink alloc] initWithBinaryMessenger:registrar.messenger];

  //sdk初始化
  // https://help.aliyun.com/document_detail/146537.htm?spm=a2c4g.11186623.0.0.11b0306e52ELgF#task-2358306
    
    // 为插件提供 ApplicationDelegate 回调方法
    [registrar addApplicationDelegate:plugin];
    NSLog(@"打印log: registerWithRegistrar");
}

// 应用程序启动回调
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //1、配置SDK。
    IMSIotSmartConfig *config = [IMSIotSmartConfig new];
    config.regionType = REGION_ALL; //取值范围参见枚举类型 `IMSRegionType`
    //这是默认配置，可以根据实际情况调整
    [IMSIotSmart sharedInstance].config = config;
    //2、设置安全图片。
    [[IMSIotSmart sharedInstance] setAuthCode:@"china_production"];
    
    //统一设置所有模块的日志 tag 输出级别
    [IMSLog setAllTagsLevel:IMSLogLevelAll];
    //可选：设置是否开启日志的控制台输出，建议在release版本中不要开启。
    [IMSLog showInConsole:YES];
    //设置App可配网的产品列表
    [[IMSIotSmart sharedInstance] configProductScope:PRODUCT_SCOPE_ALL];
    //3、启动初始化
    [[IMSIotSmart sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
    NSLog(@"打印log: didFinishLaunchingWithOptions IMSIotSmart 初始化完成");
    NSString *shortRegionId = [[IMSIotSmart sharedInstance]  shortRegionId];
    NSLog(@"shortRegionId=%@",shortRegionId);
    
    
    //设置国家，不然配网会失败
    [[IMSIotSmart sharedInstance] getCountryList:^(NSError * _Nullable error, NSArray<IMSIotCountry *> * _Nullable countryList) {
            // 返回的countryList为原始数据
            // 您可以基于这些原始数据设计UI呈现国家列表
//        NSLog(@"getCountryList=%@",countryList);
//        [[IMSIotSmart sharedInstance] setCountry:(countryList[0]) callback:^(BOOL needRestartApp) {
//            NSLog(@"setCountry=%@",countryList[0].code);
//        }];
        for (int i = 0; i < countryList.count; i++) {
            NSLog(@"country=%@,code=%@",countryList[i].areaName,countryList[i].code);
            if([countryList[i].code  isEqual: @"86"]){
                NSLog(@"setCountry country=%@,code=%@",countryList[i].areaName,countryList[i].code);
                [[IMSIotSmart sharedInstance] setCountry:(countryList[i]) callback:^(BOOL needRestartApp) {
                    NSLog(@"setCountry callback country=%@,code=%@",countryList[i].areaName,countryList[i].code);
                }];
            }
            
        }
        
    }];

    return YES;
}


- (void)startAddDeviceWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
    NSLog(@"打印log: startAddDevice");
    [kLkAddDevBiz startAddDevice:self];
}

// 实现配网接口
- (void)startAddDeviceByBroadcastProductKey:(NSString *)productKey productId:(NSString *)productId error:(FlutterError *_Nullable *_Nonnull)error {
    NSLog(@"打印log: startAddDeviceByBroadcastProductKey");
    
    //方式一：指定productKey方式
    IMLCandDeviceModel *model = [[IMLCandDeviceModel alloc] init];
    model.productKey = productKey;
    model.productId = productId;
    model.linkType = ForceAliLinkTypeBroadcast;
    [kLkAddDevBiz setDevice:model];
    
    [self startAddDeviceWithError:error];
}

- (void)startAddDeviceBySoftAPProductKey:(NSString *)productKey productId:(NSString *)productId error:(FlutterError *_Nullable *_Nonnull)error{
    NSLog(@"打印log: startAddDeviceBySoftAPProductKey");
    IMLCandDeviceModel *model = [[IMLCandDeviceModel alloc] init];
    model.productKey = productKey;
    model.productId = productId;
    model.linkType = ForceAliLinkTypeSoftap;
    [kLkAddDevBiz setDevice:model];
    
    [self startAddDeviceWithError:error];
}
- (void)startAddDeviceByBLEProductKey:(NSString *)productKey productId:(NSString *)productId error:(FlutterError *_Nullable *_Nonnull)error{
    NSLog(@"打印log: startAddDeviceByBLEProductKey");
    
    //方式一：指定productKey方式
    IMLCandDeviceModel *model = [[IMLCandDeviceModel alloc] init];
    model.productKey = productKey;
    model.productId = productId;
    model.linkType = ForceAliLinkTypeBLE;
    [kLkAddDevBiz setDevice:model];
    
    [self startAddDeviceWithError:error];
}


- (void)toggleProvisionSsid:(NSString *)ssid password:(NSString *)password timeout:(NSNumber *)timeout error:(FlutterError *_Nullable *_Nonnull)error{
    NSLog(@"打印log: toggleProvisionSsid");
    [kLkAddDevBiz toggleProvision:ssid pwd:password timeout:timeout];
}
- (void)getDeviceTokenDeviceName:(NSString *)deviceName productKey:(NSString *)productKey timeout:(NSNumber *)timeout interval:(NSNumber *)interval error:(FlutterError *_Nullable *_Nonnull)error{
    NSLog(@"打印log: getDeviceTokenDeviceName,deviceName=%@,productKey=%@",deviceName,productKey);
    
    /**
    * 第一步：获取绑定token
    */
    // self.productKey 和 self.deviceName 是配网成功后返回的设备模型中的 productKey 和 deviceName
    [[IMLLocalDeviceMgr sharedMgr] getDeviceToken:productKey deviceName:deviceName timeout:60 resultBlock:^(NSString *token, BOOL boolSuccess) {
        NSLog(@"主动获取设备token：%@，boolSuccess：%d", token, boolSuccess);
        if(token){
            // 拿到绑定需要的token
            /**
            * 第二步：调用绑定接口
            */
            FLTGetTokenResult *result = [[FLTGetTokenResult alloc] init];
            result.token = token;
            [flutterAliLink getDeviceTokenOnSuccessGetTokenResult:(result) completion:^(NSError * _Nullable) {
            
            }];
//            FlutterError *flutterError = [[FlutterError alloc] init];
            [self getIotIdToken:(token) error:NULL];
            
        } else{
            NSLog(@"获取token失败(超时)");
            FLTDCErrorCode  *errorCode = [[FLTDCErrorCode  alloc] init];
            [flutterAliLink getDeviceTokenOnFailDcErrorCode:(errorCode) completion:^(NSError * _Nullable) {
                
            }];
        }
        
    }];
}


- (void)authCodeLoginAuthCode:(nonnull NSString *)authCode error:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
   
    NSLog(@"oauthWithThirdParty,authCode=%@",authCode);
    id<ALBBOpenAccountSSOService> ssoService = ALBBService(ALBBOpenAccountSSOService);
    [ssoService oauthWithThirdParty:authCode delegate:self];
    NSLog(@"oauthWithThirdParty 调用结束");
 
}


- (void)startDiscoveryWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
    NSLog(@"打印log: startDiscoveryWithError");
    // 本地发现入口
    [[IMLLocalDeviceMgr sharedMgr] startDiscovery:^(NSArray *devices, NSError *err) {
            //devices 为 IMLCandDeviceModel 对象array，
            // 可根据 IMLCandDeviceModel 中的 devType 区分待配网设备联网类型:
            // devType 为@"ble_subtype_2" 代表蓝牙辅助配网设备*/
        NSLog(@"打印log: todo startDiscovery found device");
        NSMutableArray *array = [NSMutableArray array];
        for (int i = 0; i < devices.count; i++) {
            IMLCandDeviceModel *device = devices[i];
            NSLog(@"打印log: todo startDiscovery found device.mac %@",device.mac);
            FLTDeviceInfo *flutterDevice = [[FLTDeviceInfo alloc] init];
            flutterDevice.token = device.token;
            flutterDevice.deviceName = device.deviceName;
            flutterDevice.productKey = device.productKey;
            flutterDevice.mac = device.mac;
            [array addObject:(flutterDevice)];
        }
        
        
        //回调
        [flutterAliLink onDeviceFoundType:(@0)
                              description:(@"") deviceInfos:(array) completion:^(NSError * _Nullable) {
            
        }];
        
        
        
    }];
}

- (void)stopDiscoveryWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
    NSLog(@"打印log: stopDiscoveryWithError");
    // 停止发现设备
    [kLKLocalDeviceMgr stopDiscovery];
}

- (void)stopAddDeviceWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
    NSLog(@"打印log: stopAddDeviceWithError");
    [kLkAddDevBiz stopAddDevice];
}

- (void)getIotIdToken:(nonnull NSString *)token error:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
    NSLog(@"打印log: getIotIdToken");
    
    // 构建请求
    NSDictionary *params = @{@"token":token};
    IMSIoTRequestBuilder *builder = [[IMSIoTRequestBuilder alloc] initWithPath:@"/awss/token/check"
                                                                    apiVersion:@"1.0.10"
                                                                        params:params];
    // 可选参数
    // [builder setHost:@"xxx"];//指定API host
    // [builder setScheme:@"https"];

    //通过 IMSRequestClient 发送请求
    [IMSRequestClient asyncSendRequest:builder.build responseHandler:^(NSError * _Nullable error, IMSResponse * _Nullable response) {
        NSLog(@"打印log: getIotIdToken asyncSendRequest error=%@",error);
        if (error != NULL) {
            //处理Error，非服务端返回的错误都通过该Error回调
            [flutterAliLink onGetIotIdResultResult:(@0) iotId:(0) completion:^(NSError * _Nullable) {
            
            }];
        } else {
            if (response.code == 200) {
                //成功，处理response.data的iot字段
                NSString* jsonStr = [NSString stringWithFormat:@"%@",response.data];
                NSLog(@"asyncSendRequest jsonStr=%@",jsonStr);
                
                /**
                 {
                     deviceName = 849dc220c43c;
                     iotId = fY4F8YCwzhNJgspdgFEi000000;
                     productKey = a1T5Pde7XEc;
                 }
                 */
                // 怎么拿到 iotId呢
                
                
                // todo 通过正则找到iotId
                // todo 通过;裁剪，然后替换掉iotId、空格、= {}、换行
                NSArray *array = [jsonStr componentsSeparatedByString:@";"]; //从字符A中分隔成2个元素的数组
                NSLog(@"asyncSendRequest array:%@",array); //结果是adfsfsfs和dfsdf
                
                for (int i = 0; i < array.count; i++) {
                    NSLog(@"asyncSendRequest,array[i]=%@", array[i]);
                    NSString* iotIdString = [NSString stringWithFormat:@"%@",array[i]];
                    if ([iotIdString rangeOfString:@"iotId"].location != NSNotFound) {
                        //:iotId = fY4F8YCwzhNJgspdgFEi000000
                        NSLog(@"asyncSendRequest iotIdString=%@",iotIdString);
                        //去空格
                        NSString* jsonStr2 =  [iotIdString stringByTrimmingCharactersInSet:(NSCharacterSet.whitespaceAndNewlineCharacterSet)];
                        NSLog(@"asyncSendRequest jsonStr2=%@",jsonStr2);
                        
                        NSString *jsonStr3 = [jsonStr2 stringByReplacingOccurrencesOfString:@"=" withString:@""];
                        NSLog(@"asyncSendRequest jsonStr3=%@",jsonStr3);
                        NSString *jsonStr4 = [jsonStr3 stringByReplacingOccurrencesOfString:@"iotId" withString:@""];
                        NSLog(@"asyncSendRequest jsonStr4=%@",jsonStr4);
                        NSString *jsonStr5 = [jsonStr4 stringByReplacingOccurrencesOfString:@" " withString:@""];
                        NSLog(@"asyncSendRequest jsonStr5=%@",jsonStr5);
                        NSString* iotId = jsonStr5;
                        [flutterAliLink onGetIotIdResultResult:(@1) iotId:(iotId) completion:^(NSError * _Nullable) {
                        
                        }];
                    }
                    
                }
               
            }
            else {
                //处理服务端错误，可通过response.localizedMsg展示错误Toast
                [flutterAliLink onGetIotIdResultResult:(@0) iotId:(@0) completion:^(NSError * _Nullable) {
                
                }];
            }
        }
    }];
}

/// OTA 三个方法需要实现 todo
- (void)checkOtaUpgradeInfoIotId:(nonnull NSString *)iotId completion:(nonnull void (^)(FLTOtaNewVersionInfo * _Nullable, FlutterError * _Nullable))completion {
    
}


- (void)getOtaProgressIotId:(nonnull NSString *)iotId completion:(nonnull void (^)(FLTOtaUpgradeProgress * _Nullable, FlutterError * _Nullable))completion {
    
}


- (void)startOtaIotId:(nonnull NSString *)iotId completion:(nonnull void (^)(NSNumber * _Nullable, FlutterError * _Nullable))completion {
    
}


//配网回调 start

- (void)notifyPrecheck:(BOOL)success withError:(NSError *)err
{
    NSLog(@"notifyPrecheck callback err : %@", err);
    FLTDCErrorCode  *errorCode = [[FLTDCErrorCode  alloc] init];
    errorCode.msg = @"-1";
    if(success){
        [flutterAliLink onPreCheckResult:(@1) dcErrorCode:(errorCode) completion:^(NSError * _Nullable) {
            
        }];
    } else {
        [flutterAliLink onPreCheckResult:(@0) dcErrorCode:(errorCode) completion:^(NSError * _Nullable) {
            
        }];
    }
}

- (void)notifyProvisionStatus:(LKProvisonStatus)provisionStatus boolSuccess:(BOOL)boolSuccess;
{
    NSLog(@"notifyProvisionStatus callback provisionStatus:%d boolSuccess:%d", provisionStatus, boolSuccess);
    // 设备回复 switch ap 请求，提示用户切换回之前的 wifi

    [flutterAliLink onProvisionStatusCode:@1 msg:(@"暂时没实现") completion:^(NSError * _Nullable) {
    
    }];
}
/*
 设备热点状态回调，根据不同状态进行提醒。
status 状态码
1=提示应该切换到设备热点；
2=已经切换到设备热点
3=已发送数据（dic里面会有"token"）
4=应该切换回路由器
5=已经切换回路由器
*/
- (void)notifyProvisioningNoticeForSoftAp:(int)status withInfo:(NSDictionary *)dic
{
    
   
}

- (void)notifyProvisionPrepare:(LKPUserGuideCode)guideCode
{
    NSLog(@"notifyProvisionPrepare callback guide code : %ld", guideCode);
    if(guideCode == LKPGuideCodeWithUserGuideForSoftAp){
        /**
        * 第三步：提醒用户输入切换到设备热点，切换完成后调用toggleProvision，参考inputSsidAndPassword
        */
    }
    NSLog(@"notifyProvisionPrepare 模拟输入密码");
    [self inputSsidAndPassword];
}

- (void)inputSsidAndPassword
{
    NSString *ssid = @"wifi";
    NSString *password = @"lanshifu";
    NSInteger timeout = 60;//(单位秒,s);
    [kLkAddDevBiz toggleProvision:ssid pwd:password timeout:timeout];
}

-(void)notifyProvisioning
{
    NSLog(@"notifyProvisioning callback(正在进行配网...) ");
    [flutterAliLink onProvisioningWithCompletion:^(NSError * _Nullable) {
        
    }];
}

/**
* 第四步：监听结果回调
*/
- (void)notifyProvisionResult:(IMLCandDeviceModel *)candDeviceModel withProvisionError:(NSError *)provisionError
{
    NSLog(@"notifyProvisionResult：candDeviceModel= %@",candDeviceModel);
    FLTDCErrorCode  *errorCode = [[FLTDCErrorCode  alloc] init];
    FLTDeviceInfo  *deviceInfo = [[FLTDeviceInfo  alloc] init];
    if(candDeviceModel != NULL){
        deviceInfo.token = candDeviceModel.token;
        deviceInfo.productKey = candDeviceModel.productKey;
        deviceInfo.deviceName = candDeviceModel.deviceName;
        [flutterAliLink onProvisionedResultSuccess:(@1) deviceInfo:(deviceInfo) dcErrorCode:(errorCode) completion:^(NSError * _Nullable) {
        
        }];
    } else {
        [flutterAliLink onProvisionedResultSuccess:(@0) deviceInfo:(deviceInfo) dcErrorCode:(errorCode) completion:^(NSError * _Nullable) {
        
        }];
    }
    
}
//配网回调 end

/// Oauth授权登录回调
///https://help.aliyun.com/document_detail/130355.htm?spm=a2c4g.11186623.0.0.22ec769cAl1npX#concept-1698060
- (void)openAccountOAuthError:(NSError *)error Session:(ALBBOpenAccountSession *)session {
    NSLog(@"openAccountOAuthError,error= %@",error);
    NSLog(@"openAccountOAuthError,session= %@",session);
    
    if (error == NULL) {
        //登录成功，发送登录成功通知，身份认证SDK会监听该通知并创建和管理用户身份凭证
        NSString *loginNotificationName = [[IMSAccountService sharedService].sessionProvider accountDidLoginSuccessNotificationName];
        [[NSNotificationCenter defaultCenter] postNotificationName:loginNotificationName object:nil];
        NSLog(@"onAuthCodeLoginSuccessWithCompletion");
        [flutterAliLink onAuthCodeLoginSuccessWithCompletion:^(NSError * _Nullable) {
            
        }];
    } else {
        //处理登录失败
        NSLog(@"onAuthCodeLoginFailedCode");
        [flutterAliLink onAuthCodeLoginFailedCode:(@-1)
                                              msg:(@"error") completion:^(NSError * _Nullable) {
            
        }];
    }
}

@end
